package main

import (
	"blog2021/configs"
	"blog2021/controller"
	"blog2021/middleware"
	"blog2021/tools/github_markdown_util"
	"blog2021/tools/logger"
	"blog2021/tools/timeutil"
	"blog2021/tools/util"
	"html/template"
	"path/filepath"

	"github.com/gin-contrib/multitemplate"
	"github.com/gin-gonic/gin"
)

func MarkdownHtml(text string) template.HTML {
	return template.HTML(github_markdown_util.Markdown([]byte(text)))
}

func loadTemplates(templatesDir string) multitemplate.Renderer {
	// template自定义函数
	funcMap := template.FuncMap{
		"TemplateHtml":   util.TemplateHtml,
		"MarkdownHtml":   MarkdownHtml,
		"SplitSemicolon": util.SplitSemicolon,
		"TimeFormat":     timeutil.Format,
	}

	r := multitemplate.NewRenderer()

	// 非模板嵌套
	htmls, err := filepath.Glob(templatesDir + "/htmls/*.html")
	if err != nil {
		panic(err.Error())
	}
	for _, html := range htmls {
		r.AddFromGlob(filepath.Base(html), html)
	}

	// 布局模板
	layouts, err := filepath.Glob(templatesDir + "/layouts/*.html")
	if err != nil {
		panic(err.Error())
	}

	// 嵌套的内容模板
	includes, err := filepath.Glob(templatesDir + "/includes/*.html")
	if err != nil {
		panic(err.Error())
	}

	for _, include := range includes {
		files := []string{}
		files = append(files, templatesDir+"/frame.html", include)
		files = append(files, layouts...)
		r.AddFromFilesFuncs(filepath.Base(include), funcMap, files...)
	}

	return r
}

func startServer() {
	router := gin.Default()
	router.HTMLRender = loadTemplates(configs.AppDir("view"))

	// 中间件
	router.Use(middleware.AccessLog())
	router.Use(middleware.Session())

	// 静态目录
	router.Static("/static", configs.AppDir("view/static"))
	router.Static("/upload", configs.AppDir("view/upload"))
	router.StaticFile("/favicon.ico", configs.AppDir("view/static/img/favicon.ico"))
	router.StaticFile("/feed.xml", configs.AppDir("view/static/feed.xml"))
	router.StaticFile("/robots.txt", configs.AppDir("./robots.txt"))
	router.StaticFile("/sitemap.xml", configs.AppDir("./sitemap.xml"))

	// 错误路由
	router.NoMethod(controller.NotFound)
	router.NoRoute(controller.NotFound)

	// 路由
	router.GET("/", controller.Index)
	router.GET("/post/:id", controller.Post)
	router.GET("/about", controller.About)
	router.POST("/about/add-comment", controller.AboutAddComment)
	router.GET("/archive", controller.ArchiveDesc)
	router.GET("/archive/desc", controller.ArchiveDesc)
	router.GET("/archive/asc", controller.ArchiveAsc)
	router.GET("/tags/:name", controller.Tag)
	router.GET("/tags/:name/:name2", controller.Tag) // 解决：/tags/c/c++
	router.GET("/search", controller.Search)
	router.GET("/bingpage", controller.BingPage)
	router.GET("/captcha", controller.Captcha)
	router.POST("/uploadimage", controller.UploadImage)
	router.GET("/create/feed", controller.Feed)

	router.GET("/login", controller.Login)
	router.POST("/login", controller.OnLogin)
	router.GET("/logout", controller.Logout)
	router.GET("/tools", controller.Tools)
	router.GET("/html2markdown", controller.Html2markdown)

	router.GET("/chart/postaccess", controller.ChartPostAccess)
	router.GET("/chart/hourcount/:count", controller.ChartHourCount)
	router.GET("/aichat", controller.AIChat)
	router.GET("/aichat/question", controller.AIChatQuestion)
	router.GET("/gather", controller.Gather)
	router.GET("/gather/reload", controller.GatherReload)
	router.POST("/gather/:name", controller.GatherName)

	// 外部接口
	api := router.Group("api", middleware.Api())
	{
		api.GET("/bingtoday", controller.BingToday)
		api.GET("/bingdate", controller.BingDate)
	}

	// 需要授权的路由
	auth := router.Group("admin", middleware.Auth())
	{
		auth.Use(middleware.Session())
		auth.GET("/edit/:id", controller.Edit)
		auth.GET("/edit", controller.Edit)
		auth.GET("/delete/:id", controller.DeletePost)
		auth.POST("/edit/", controller.OnEdit)
	}

	const PORT = ":3000"
	logger.Infof("----------start listen%s mode:%s----------\n", PORT, gin.Mode())
	if err := router.Run(PORT); err != nil {
		logger.Error(err)
	}
}
